import pygame,pygame.locals
import sys,os,time

#   创建时间：  2021-05-23  14:46   by  炸天帮成员
#   该文件创建于 _8_pygame_demo_color_dictWithClass_1_ExOK.py 之后的原因是：
#   本文件实际上是 _8_pygame_demo_color_dictWithClass_1_ExOK.py 的原型。
#   只不过昨天晚上太晚了，就直接在_8_pygame_demo_color_dictWithClass_ExOK.py的基础上修改成了
#   _8_pygame_demo_color_dictWithClass_1_ExOK.py
#   即本文件实际上为第一个从
#   _6_pygame.demo_colorBlock_3_PNG_ExOK.py
#   升级上来的文件。
#   时间控制绿色方块的移动见 _8_pygame_demo_color_dictWithClass_1_ExOK.py
def game_init():
    pygame.init()
    pygame.display.init()

def refresh_pygame():                   #   这个refresh_pygame()函数要和 pygame.display.update() 一起结合使用。
                                        #   这样程序才不会运行至一半导致崩溃，另外仅有move_ip()而无blit()，也会导致图片不会刷新。
    FPS = 60
    pygame.time.Clock().tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.locals.QUIT:
            pygame.quit()
            sys.exit()
    DISPLAYSURF.blit(BKG_IMAGE,(0,0))   #   即背景图片的图层最先刷新，因为后出的blit()加载图片 会覆盖上一个blit()加载图片
                                        #   如果将此处注释掉 ， 则 那几个 IRO_BLOCK 中的 move() 会产生拖影。
                                        #   如果将背景图片的刷新给放入IRO_BLOCK的load()中，就会出现只显示 最后的blit()加载图片
COLOR_BLACK = (0,0,0)
COLOR_WHITE = (255,255,255)
COLOR_BKG = COLOR_BLACK

WORKPLACE_PATH = os.getcwd()
IMAGE_PATH = f'{WORKPLACE_PATH}\COLOR_BLOCK_PNG\\'

WINDOW_X_MAX = 400
WINDOW_Y_MAX = 400
DISPLAYSURF = pygame.display.set_mode((WINDOW_X_MAX,WINDOW_Y_MAX))
DISPLAYSURF.fill(COLOR_BKG)
BKG_IMAGE = pygame.image.load(IMAGE_PATH + 'whiteBKG.png')

GREEN_BLOCK_DICT = {            #   原始绿色方块字典的样式
    '0':{
        'ID':0,
        'TYPE':'GREEN_BLOCK',
        'NAME':'GREEN_BLOCK_0',
        'ALIVE_STATUS':False,
        'X_SIZE':40,
        'Y_SIZE':40,
        'START_POSITION':(WINDOW_X_MAX,WINDOW_Y_MAX/2),
        'MOVE_STEP':-5,
        'IMAGE':pygame.image.load(IMAGE_PATH + 'greenBlock.png'),
    }
}

class IRO_BLOCK(pygame.sprite.Sprite):
    def __init__(self,BLOCK_ID,BLOCK_TYPE,BLOCK_NAME,\
                      BLOCK_ALIVE_STATUS,BLOCK_X_SIZE,BLOCK_Y_SIZE,\
                      BLOCK_START_POSITION,BLOCK_MOVE_STEP,BLOCK_IMAGE):
        super().__init__()
        self.ID = BLOCK_ID
        self.TYPE = BLOCK_TYPE
        self.NAME = BLOCK_NAME
        self.ALIVE_STATUS = BLOCK_ALIVE_STATUS
        self.X_SIZE = BLOCK_X_SIZE
        self.Y_SIZE = BLOCK_Y_SIZE
        self.START_POSITION = BLOCK_START_POSITION
        self.MOVE_STEP = BLOCK_MOVE_STEP
        self.IMAGE = BLOCK_IMAGE

        self.SURF = pygame.Surface((self.X_SIZE,self.Y_SIZE))
        self.RECT = self.SURF.get_rect(center = self.START_POSITION)

    def load(self):
        DISPLAYSURF.blit(self.IMAGE,self.RECT)


    def move(self):
        self.RECT.move_ip(self.MOVE_STEP,0)
        if self.RECT.right < 0 :
            self.ALIVE_STATUS = False   #   如果绿色方块移出pygame的窗口，则设定该绿色方块已死亡。
            self.IRO_BLOCK_LOAD_STATE = False   #   绿色方块死亡，即意味着load()函数的标志位 回归 False
        else :
            self.ALIVE_STATUS = True    #   如果绿色方块未移出pygame的窗口，则设定该绿色方块存活。
            self.IRO_BLOCK_LOAD_STATE = True    #   绿色方块存活，即意味着load()函数的标志位 保持 True
# 以下4行用于测试   将字典中的条目  印射到  IRO_BLOCK   这个    CLASS中，并实例化(对象OBJECT化)
# GREEN_BLOCK_DICT['0'] = IRO_BLOCK(GREEN_BLOCK_DICT['0']['ID'],GREEN_BLOCK_DICT['0']['TYPE'],GREEN_BLOCK_DICT['0']['NAME'],\
#                     GREEN_BLOCK_DICT['0']['ALIVE_STATUS'],GREEN_BLOCK_DICT['0']['X_SIZE'],GREEN_BLOCK_DICT['0']['Y_SIZE'],\
#                     GREEN_BLOCK_DICT['0']['START_POSITION'],GREEN_BLOCK_DICT['0']['MOVE_STEP'],GREEN_BLOCK_DICT['0']['IMAGE'])
# print("GREEN_BLOCK_DICT['0'] = ",GREEN_BLOCK_DICT['0'],'\n类型为 ： ',type(GREEN_BLOCK_DICT['0']))

GREEN_BLOCK_MAX_NUMBER = 1              #   设置 最多有  GREEN_BLOCK_MAX_NUMBER  个绿色方块。使用时从下标0开始。
def NEW_GREEN_BLOCK_OBJ(BLOCK_MAX_NUMBER):
    for i in range (0,GREEN_BLOCK_MAX_NUMBER):
        GREEN_BLOCK_DICT[str(i)] = {
                                    'ID':i,
                                    'TYPE':'GREEN_BLOCK',
                                    'NAME':f'GREEN_BLOCK_{i}',
                                    'ALIVE_STATUS':False,
                                    'X_SIZE':40,
                                    'Y_SIZE':40,
                                    'START_POSITION':(WINDOW_X_MAX,WINDOW_Y_MAX/2),
                                    'MOVE_STEP':-5,
                                    'IMAGE':pygame.image.load(IMAGE_PATH + 'greenBlock.png'),
                                    }
        GREEN_BLOCK_DICT[str(i)] = IRO_BLOCK(GREEN_BLOCK_DICT[str(i)]['ID'],GREEN_BLOCK_DICT[str(i)]['TYPE'],GREEN_BLOCK_DICT[str(i)]['NAME'],\
                    GREEN_BLOCK_DICT[str(i)]['ALIVE_STATUS'],GREEN_BLOCK_DICT[str(i)]['X_SIZE'],GREEN_BLOCK_DICT[str(i)]['Y_SIZE'],\
                    GREEN_BLOCK_DICT[str(i)]['START_POSITION'],GREEN_BLOCK_DICT[str(i)]['MOVE_STEP'],GREEN_BLOCK_DICT[str(i)]['IMAGE'])
# 以下两行为测试    def NEW_GREEN_BLOCK_OBJ(BLOCK_MAX_NUMBER)   函数用。
# NEW_GREEN_BLOCK_OBJ(GREEN_BLOCK_MAX_NUMBER)
# print("GREEN_BLOCK_DICT = ",GREEN_BLOCK_DICT,'\nGREEN_BLOCK_DICT类型为 ： ',type(GREEN_BLOCK_DICT),'\nGREEN_BLOCK_DICT个数为 ：',len(GREEN_BLOCK_DICT))

if __name__ == "__main__":
    game_init()
    NEW_GREEN_BLOCK_OBJ(GREEN_BLOCK_MAX_NUMBER)
    print("GREEN_BLOCK_DICT = ",GREEN_BLOCK_DICT,'\nGREEN_BLOCK_DICT类型为 ： ',type(GREEN_BLOCK_DICT),'\nGREEN_BLOCK_DICT个数为 ：',len(GREEN_BLOCK_DICT))

    PYGAME_START_TIME = time.time()
    print('游戏启动时间为 : ',time.ctime(PYGAME_START_TIME))
    SET_PYGAME_RUNNING_TIME = 10                                         #   设定pygame的运行时间，单位为s
    while time.time()-PYGAME_START_TIME < SET_PYGAME_RUNNING_TIME :     #   使用time来控制pygame的整体运行时间。
        refresh_pygame()
        GREEN_BLOCK_DICT['0'].load()    #   注意若用于显示Rect对象的blit()未写，而只写move_ip()，则在后台中，pygame.Rect()对象是依旧在移动的，但不会被显示出来。
        GREEN_BLOCK_DICT['0'].move()    #   故要放弃以前的写法，使用类似于本程序中在blit()的包裹函数load()和move()两个函数上动手脚，这样才能在规定时间里显示并移动，而不是 不显示并移动。
                                        #   综上2行，即pygame()将这两个东西分开的原因是，显示归显示(使用blit)，pyugame.Rect对象移动归移动(使用move_ip)，
                                        #   若要在显示的同时并移动，则必须blit和move_ip同时被调用才行。具体见self.IRO_BLOCK_LOAD_STATE这个参数出现的地方。
        pygame.display.update()
        #print("GREEN_BLOCK_DICT['0']的生存状态 : ",GREEN_BLOCK_DICT['0'].ALIVE_STATUS)
    print('游戏结束时间为 : ',time.ctime(time.time()))
    print("绿色方块的GREEN_BLOCK_DICT['0'].RECT.left = ",GREEN_BLOCK_DICT['0'].RECT.left)


    #   总结：
    #       2021-05-23 18:20 by 炸天帮成员
    #       在写完 _8_pygame_demo_color_dictWithClass_2_Multi_TimeControl_ExOK.py 后
    #       本文件中的 load()和move()是分开的，没有任何关联，即如下关系：
    #       load() -> 纯blit() -> 仅用于在pygame窗口上的某个位置显示 pygame.Rect对象的图像，和移动无关，只要调用就显示。
    #       move() -> 纯move_ip() -> 仅用于移动pygame.Rect对象，和显示与否无关，只要调用就移动。
    #       即若只是用 move() 而不使用 load() ，pygame.Rect对象也是在移动的，只是不在pygame窗口中显示而已。

    #       故，为了实现在某个时间点，在pygame窗口中的某个点上 显示图像 并在显示后才发生移动，
    #       需要添加一个 允许发生移动函数的Flag ,该Flag需要在 调用 blit() 后产生，即在load()函数中被首次改变状态值。比如从False -> True.
    #       然后 只有当 该Flag == True 时， move_ip()才会有效，这个判断就需要写在 move()中。
    #       且当绿色方块 移出pygame的窗口时，即绿色方块被判定为死亡时，
    #       该Flag将重新被赋值为False(初始值)。
    #       详见_8_pygame_demo_color_dictWithClass_1_ExOK.py